﻿using System;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;

//svnkit imports
using org.tmatesoft.svn.core;
using org.tmatesoft.svn.core.wc;

namespace Subsync.Core.Subversion
{
    class SVNSwitch : CommandBase
    {
        // Initialise variables with default settings.
        public long rev_no; //return value of doSwitch
		public SVNURL url; //url of new repository
		public java.io.File destination_path; //path of local copy
		public SVNRevision peg_revision = SVNRevision.UNDEFINED;
		public SVNRevision revision = SVNRevision.HEAD; //head means latest revision
		public SVNDepth depth = SVNDepth.INFINITY; //infinity means recursive
		public bool allow_unversioned_obstructions = true; //tolerate existing items in added path
		public bool depth_is_sticky = true;

		// Minimal constructor.
		public SVNSwitch(string url) {
			Debug.WriteLine("SVN Switch minimal Constructor with defaults");
            this.lazySwitch(url);
		}
		
		// Full constructor.
		public SVNSwitch(string url,string dest_path,
		                      SVNRevision peg_rev, SVNRevision co_rev,
		                      SVNDepth depth, Boolean allow_unv_obs, Boolean depth_sticky) 
		{
			Debug.WriteLine("SVN Switch Full Constructor");
			
			this.url = SVNURL.parseURIEncoded(url);
			this.destination_path = new java.io.File(dest_path);
			this.peg_revision = peg_rev;
			this.revision = co_rev;
			this.depth = depth;
			this.allow_unversioned_obstructions = allow_unv_obs;
            this.depth_is_sticky = depth_sticky;
		}

        public void lazySwitch(string url)
        {
            this.url = SVNURL.parseURIEncoded(url);
            this.destination_path = new java.io.File(Directory.GetCurrentDirectory() + "\\");
        }

        public override void Execute()
        {
            Debug.WriteLine("SVN Switch Execution");

            //Library setup
            Tools.setupLibrary();

            //load up the clients
            SVNClientManager cm = SVNClientManager.newInstance();
            SVNUpdateClient uc = cm.getUpdateClient();

            try
            {
                rev_no = uc.doSwitch(this.destination_path, this.url,
                            this.peg_revision, this.revision, this.depth,
                            this.allow_unversioned_obstructions, this.depth_is_sticky);
                Console.WriteLine("File is updated to revision {0}", rev_no);
            }
            catch (SVNException e)
            {
                //we convert this exception to a non SVNKit exception.
                //we want to minimize interfacing with SVNkit outside of this namespace (abstraction)
                throw new SVNExecuteException(e.getMessage());
            }
        }
        public override Dictionary<string, List<object>> getTokens ()
		{
			Dictionary<string, List<object>> ret = new Dictionary<string, List<object>> ();
			ret.Add("Switch",new List<object>() {"sw","switch"});
			return ret;
		}
		
		public override List<KeyValuePair<string,initPointer>> getInitPointers() {
			List<KeyValuePair<string,initPointer>> ret = new List<KeyValuePair<string,initPointer>>();
			ret.Add(new KeyValuePair<string,initPointer>("Switch",new initPointer(this.handleCLI)));
			return ret;
		}
		
		public void handleCLI(Dictionary<string,List<object>> tokens) {
			if (tokens["Switch"].Count != 1) {
				Console.WriteLine("Not enough arguments: Switch requires at least 1 argument (url)");
				return;
			}
			string url = (string) tokens["Switch"][0];
            this.lazySwitch(url);
            this.Execute();
        }

        public SVNSwitch() {}
    }
}
